不知不覺到了第5天了,這幾天都在忙鐵人賽文章,突然覺得生活好充實呀!今天我們繼續來講資料傳遞的方式。
重提一下昨天最後的範例,我們建立了一個Member的List物件,利用ViewBag或ViewData將資料帶到View。
        public ActionResult ShowMembers()
        {
            var memberA = new Member() { Id = 1, Name = "Alex", Age = 12 };
            var memberB = new Member() { Id = 2, Name = "Ben", Age = 34 };
            var memberC = new Member() { Id = 3, Name = "Carol", Age = 56 };
            var memberList = new List<Member>() { memberA, memberB, memberC };
            ViewData["Members"] = memberList;
            return View();
        }
但通常遇到比較大量複雜的資料需要傳遞時,常用的做法是直接將物件放入View()裡面的參數,傳遞至檢視頁面,例如將上方的Code改寫如下:
        public ActionResult ShowMembers()
        {
            var memberA = new Member() { Id = 1, Name = "Alex", Age = 12 };
            var memberB = new Member() { Id = 2, Name = "Ben", Age = 34 };
            var memberC = new Member() { Id = 3, Name = "Carol", Age = 56 };
            var memberList = new List<Member>() { memberA, memberB, memberC };
            return View(memberList);
        }
我們將滑鼠移到return View();的View上方,可以看到View()方法可以接受object型別的資料(model)當作參數傳入。
接著我們切換到View檢視,修改Code如下:
@using MyFirstWebApp.Models
@model IEnumerable<Member>
@{
    ViewBag.Title = "ShowMembers";
}
<h2>ShowMembers</h2>
<div>
    @{
        foreach (var member in Model)
        {
            <label>會員編號:</label> @member.Id
            <br />
            <label>會員姓名:</label> @member.Name
            <br />
            <label>年齡:</label> @member.Age
            <hr />
        }
    }
</div>
首先可以看到foreach迴圈裡面的資料物件,會使用Model這個字眼,且在最上面2行使用@model關鍵字來綁定Model的型別為IEnumrable<Member>,因為List本身就實作了IEnumrable介面。這邊要寫List<Member>也可以。畫面執行如下:
假如我們先將@model IEnumerable<Member>這行註解起來(※註解的快捷鍵為:ctrl+k 再按 ctrl+c),將頁面執行後會發現其實沒有差別,資料還是可以順利顯示。但使用@model將資料模型轉為強型別的好處在於,可以使用開發工具內建的 IntelliSense 支援,幫助我們快速打程式碼與避免輸入錯誤。
延續上個範例,我們思考一下,假如需要傳遞的資料來自於2個不同類別的物件該怎麼辦?
比如我們先在Models資料夾新增一個Product類別如下:
    public class Product
    {
        public int Number { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }
    }
然後在DemoController底下新增ShowShoppingList()動作方法,並建立一個Member物件與List<Product>物件,Code如下:
        public ActionResult ShowShoppingList()
        {
            var member = new Member() { Id = 1, Name = "Alex", Age = 12 };
            var products = new List<Product>();
            products.Add(new Product { Number = 1, Name = "Apple", Price = 30 });
            products.Add(new Product { Number = 2, Name = "Banana", Price = 50 });
            products.Add(new Product { Number = 3, Name = "Cherry", Price = 30 });
            return View();
        }
當我們想要顯示這個會員所購買的產品清單時,必須同時傳遞2個物件到View,這時候就可以透過ViewModel的概念來實現了。ViewModel顧名思義就是專門給View用的Model,作法也很簡單,就是將2個類別加入一個新的ViewModel裡面的屬性,再將ViewModel傳入View就可以了。
所以我們再建立一個MemberInfoViewModel類別於Models資料夾底下,並新增Member與List<Product>屬性。
    public class MemberInfoViewModel
    {
        public Member Member { get; set; }
        public List<Product> Products { get; set; }
    }
接著修改ShowShoppingList()動作方法內容如下,重點在於建立ViewModel的物件實體,並將原本建好的member與products物件指定為ViewModel的屬性。
        public ActionResult ShowShoppingList()
        {
            var member = new Member() { Id = 1, Name = "Alex", Age = 12 };
            var products = new List<Product>();
            products.Add(new Product { Number = 1, Name = "Apple", Price = 30 });
            products.Add(new Product { Number = 2, Name = "Banana", Price = 50 });
            products.Add(new Product { Number = 3, Name = "Cherry", Price = 100 });
            var memberInfo = new MemberInfoViewModel();
            memberInfo.Member = member;
            memberInfo.Products = products;
            return View(memberInfo);
        }
最後是View的呈現,新增ShowShoppingList()方法的檢視頁面,Code如下:
@model MyFirstWebApp.Models.MemberInfoViewModel
@{
    ViewBag.Title = "ShowShoppingList";
}
<h2>ShowShoppingList</h2>
<div>
    會員編號: @Model.Member.Id
    <br />
    會員姓名: @Model.Member.Name
    <br />
    <hr />
    <ul>
        @foreach (var item in Model.Products)
        {
            <li>商品編號: @item.Number 品名: @item.Name 價格: @item.Price</li>
        }
    </ul>
</div>
這邊可以看到最上面使用@model關鍵字時將引用資料夾名稱完整打出來,就不需要再使用using了,畫面執行結果如下:
昨天和今天主要都在說明如何透過Controller的動作方法來傳遞後端資料給View,但如果使用者是在網頁上輸入一些資訊後要送到後端處理,又該怎麼做呢?明天來講講這部分,See U Tomorrow啦~
※小弟不才,在軟體的世界還只是個小菜雞,如果內容有任何謬誤或問題,還請各位大神前輩們多多批評指教~歡迎下方留言討論^^